package gzhaoku.com.common.util;

import com.alibaba.fastjson.JSON;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.apache.commons.lang3.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;

import cz.msebera.android.httpclient.Header;
import gzhaoku.com.common.Logger;
import gzhaoku.com.machinemain.BuildConfig;

public abstract class ApiCommon {

    static final Logger log = Logger.getLog(ApiCommon.class);

    protected static AsyncHttpClient client = new AsyncHttpClient();

    protected static String ApiHost = "";

    static{
        ApiHost = BuildConfig.SERVER_URL;
        client.setTimeout(15 * 1000);
    }

    protected static RequestParams sign(Map<String, Object> kv, String secret) {
        secret = StringUtils.trimToEmpty(secret);
        StringBuilder paramStr = new StringBuilder();
        Map<String, Object> sorted = new TreeMap(kv);
        RequestParams params = new RequestParams();

        for (Map.Entry<String, Object> e : sorted.entrySet()) {
            if (e.getValue() != null) {
                paramStr.append("&").append(e.getKey()).append("=").append(e.getValue().toString());
                params.add(e.getKey(), e.getValue().toString());
            }
        }

        String content = paramStr.substring(1) + "&" + secret;

        log.i("before sign:%s", content);

        String sign = sha256Hex(content);

        log.i("sign:%s", sign);

        params.add("sign", sign);
        return params;
    }

    public static String signString(Map<String, Object> kv, String secret) {
        secret = StringUtils.trimToEmpty(secret);
        StringBuilder paramStr = new StringBuilder();
        Map<String, Object> sorted = new TreeMap(kv);

        for (Map.Entry<String, Object> e : sorted.entrySet()) {
            if (e.getValue() != null) {
                paramStr.append("&").append(e.getKey()).append("=").append(e.getValue().toString());
            }
        }

        String content = paramStr.substring(1) + "&" + secret;

        log.i("before sign:%s", content);

        String sign = sha256Hex(content);

        log.i("sign:%s", sign);

        return sign;
    }


    /**
     * SHA加密
     *
     * @param strSrc 明文
     * @return 加密之后的密文
     */
    protected static String sha256Hex(String strSrc) {
        MessageDigest md = null;
        String strDes = null;
        byte[] bt = strSrc.getBytes();
        try {
            md = MessageDigest.getInstance("SHA-256");// 将此换成SHA-1、SHA-512、SHA-384等参数
            md.update(bt);
            strDes = bytes2Hex(md.digest()); // to HexString
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
        return strDes;
    }

    /**
     * byte数组转换为16进制字符串
     *
     * @param bts 数据源
     * @return 16进制字符串
     */
    protected static String bytes2Hex(byte[] bts) {
        String des = "";
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des += "0";
            }
            des += tmp;
        }
        return des;

    }

    public static class Handler extends JsonHttpResponseHandler {

        ApiCallback callback;

        Handler(ApiCallback c){
            callback = c;
        }


        @Override
        public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
            log.i("[API<-"+statusCode+"]"+(errorResponse == null ? "" : errorResponse.toString()));
            callback.onFail("无法连接服务器(-1)");
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String resp, Throwable throwable){
            log.e(throwable);
            log.i("[API<-"+statusCode+"]"+resp);
            callback.onFail("无法连接服务器(-1)");
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            log.i("[API<-]"+response.toString());
            if(response.has("status")){
                try {
                    if(response.getInt("status") == 0){
                        callback.onOk(JSON.parseObject(response.getJSONObject("data").toString()));
                    }else{
                        callback.onFail(response.getString("msg"));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                    callback.onFail("无法连接服务器(-3)");
                }
            }else{
                callback.onFail("无法连接服务器(-2)");
            }
        }

    }
}